<template>
  <div class="container width-800">
    <div class="room">
      <div class="blog-chat--item" :class="chat.dis" v-for="chat in chatList" :key="chat.key">
        <span v-if="chat.nikname" class="blog-chat--nikname">{{ chat.nikname }}</span>
        <div class="blog-chat--box">
          <span class="blog-chat--time" v-if="chat.time">{{ chat.time }}</span>
          <p class="blog-chat--msg" v-if="chat.msg">{{ chat.msg }}</p>
        </div>
      </div>
      <div class="input display-flex">
        <el-input v-model="input" placeholder="请输入内容" @keyup.enter="sendChat"></el-input>
        <el-button class="button" type="primary" round size="mini" @click="sendChat">主要按钮</el-button>
      </div>
      <el-dialog title="输入昵称" :visible="dialogVisible" width="30%">
        输入昵称:
        <el-input v-model="nikname"></el-input>
        <span slot="footer" class="dialog-footer">
          <el-button type="primary" @click="login">确 定</el-button>
        </span>
      </el-dialog>
    </div>
  </div>
</template>

<script>
import { io } from 'socket.io-client'
import formatDate from '@/utils/formatDate'
import { v4 as uuidv4 } from 'uuid'
export default {
  data() {
    return {
      input: '',
      chatList: [],
      nikname: '',
      ws: null,
      dialogVisible: false
    }
  },
  created() {
    // 获取本地存储的昵称
    this.getNikname()
    // 建立socket连接
    this.ws = io('ws://127.0.0.1:8787', { transports: ['websocket'] })
    this.ws.on('connect', () => {
      console.log('聊天室建立连接成功！')
      if (this.nikname) {
        this.ws.emit('login', this.nikname)
      }
    })
    // 监听昵称冲突
    this.ws.on('logged_status', data => {
      console.log('data: ', data)
      if (data === 0) {
        this.$message.error('昵称已被占用，请更换昵称')
        return
      }
      if (data === 1) {
        this.dialogVisible = false
      }
    })
    // 监听聊天消息
    this.ws.on('chat', data => {
      this.serverChat(data)
    })
    // 监听退出
    this.ws.on('logout', nikname => {
      this.serverLog({ nikname, isLogin: false })
    })
    // 监听登录
    this.ws.on('logged', nikname => {
      this.serverLog({ nikname, isLogin: true })
    })
  },
  beforeDestroy() {
    //关闭socket
    this.ws.close()
  },
  methods: {
    // 获取本地存储的昵称
    getNikname() {
      const nikname = this.$store.getters.nikname || ''
      this.dialogVisible = !nikname
      this.nikname = nikname
    },
    // 登录
    login() {
      if (this.nikname.trim() === '') {
        // 信息不能为空
        this.$message.error({
          message: '昵称不能为空',
          offset: 80
        })
        return
      }
      this.ws.emit('login', this.nikname)
    },
    // 添加聊天消息
    addChat({ type = 'msg', msg = '', nikname = '', time = formatDate(), isMe = false }) {
      let dis = 'left'
      if (type === 'action') {
        dis = 'center'
      }
      if (isMe) {
        dis = 'right'
      }
      const uniqueKey = uuidv4() // 生成UUID
      this.chatList.push({
        type,
        msg,
        nikname,
        time,
        isMe,
        dis,
        key: uniqueKey // 使用UUID作为key
      })
    },
    // 发送消息
    sendChat() {
      let msg = this.input
      this.addChat({
        isMe: true,
        msg,
        nikname: this.nikname
      })
      this.ws.emit('send', msg)
      this.input = ''
    },
    // 服务器消息
    serverChat({ msg = '', nikname = 'xxx', time = '' }) {
      this.addChat({
        nikname,
        msg,
        time
      })
    },
    // 服务器登录/退出
    serverLog({ nikname, isLogin }) {
      let state = isLogin ? '进入' : '离开'
      let msg = `${nikname} ${state}了聊天室`
      this.addChat({
        type: 'action',
        msg
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.container {
  position: relative;
  border-top: 1px solid #ccc;
  .room {
    background-color: #fff;
    margin-top: 80px;
    padding: 20px;
    height: 600px;
    box-shadow: 0 0 30px rgba(0, 0, 0, 0.8) inset;
  }
  .input {
    position: absolute;
    width: 70%;
    bottom: 40px;
    left: 50%;
    padding: 20px;
    transform: translateX(-50%);
    background-color: #fff;
    .button {
      margin-left: 15px;
    }
  }
  .blog-chat--item {
    display: flex;
    flex-direction: row;
    justify-content: center;
    .blog-chat--time {
      color: #777;
    }
  }
  .blog-chat--item.left {
    justify-content: flex-start;
    .blog-chat--nikname {
      margin-right: 10px;
      font-weight: 600;
      color: skyblue;
    }
    .blog-chat--msg {
      background-color: #e6e6e6;
      padding: 5px;
      border-radius: 12px;
    }
  }
  .blog-chat--item.right {
    justify-content: flex-start;
    flex-direction: row-reverse;
    .blog-chat--time {
      color: #777;
      margin-right: 10px;
    }
    .blog-chat--nikname {
      margin-left: 10px;
      font-weight: 600;
      color: pink;
    }
    .blog-chat--msg {
      background-color: #dcf8c6;
      padding: 5px;
      border-radius: 12px;
    }
  }
}
</style>
